from werkzeug import Response
from wtforms import StringField, IntegerField
from wtforms.validators import DataRequired, length, Email, Regexp
from wtforms import ValidationError

from app.libs.enums import ClientTypeEnum
from app.libs.error_code import ClientTypeError
from werkzeug.exceptions import HTTPException, BadRequest
from app.models.user import User
from app.validators.base import BaseForm as Form


# 通用的Form， 如果还需要其他额外的验证，可以在定义其他类然后继承ClientForm
class ClientForm(Form):
    account = StringField(validators=[DataRequired(message='不允许为空'), length(
        min=5, max=32
    )])
    secret = StringField()
    type = IntegerField(validators=[DataRequired()])

    # 自定内置验证器
    def validate_type(self, value):
        try: # 如果传的值不在枚举中，也就是随便传了一个type值
            client = ClientTypeEnum(value.data) # 把数字转换成枚举类型
        except ValueError as e:
            # raise e
            raise ValidationError(str(e)) from e  # from e的好处：原始异常的信息也会被包含在新异常的上下文中
        self.type.data = client  # 这里如果不赋值会导致@api.route('/register')方法中 [form.type.data]取不到值，


# 用户邮箱注册
class UserEmailForm(ClientForm):
    account = StringField(validators=[
        Email(message='invalidate email')
    ])
    secret = StringField(validators=[
        DataRequired(),
        # password can only include letters , numbers and "_"
        Regexp(r'^[A-Za-z0-9_*&$#@]{6,22}$')
    ])
    nickname = StringField(validators=[DataRequired(),
                                       length(min=2, max=22)])

    # 验证用户是否已经注册过
    def validate_account(self, value):
        value.data = str(value.data)
        if User.query.filter_by(email=value.data).first():
            raise ValidationError("email 已经存在")

class BookSearchForm(Form):
    q = StringField(validators=[DataRequired()])